import datetime
import logging
import os
from datetime import datetime
from logging.handlers import TimedRotatingFileHandler

from config.config import MainConfig

log_path = MainConfig.logPath


def save_current_screen(driver, file_name):
    """
    保存当前屏幕
    :param driver: 浏览器
    :param file_name: 文件名
    :return:
    """
    current_date = datetime.now().strftime("%Y年%m月%d日")
    file_path = os.path.join(log_path, current_date, file_name)
    os.makedirs(os.path.dirname(file_path), exist_ok=True)
    driver.save_screenshot(file_path)


def save_full_page(driver, file_name):
    """
    保存整个页面的长截图
    :param driver: 浏览器
    :param file_name: 文件名
    :return:
    """
    current_date = datetime.now().strftime("%Y年%m月%d日")
    file_path = os.path.join(log_path, current_date, file_name)
    os.makedirs(os.path.dirname(file_path), exist_ok=True)

    # 获取页面高度
    total_height = driver.execute_script("return document.body.scrollHeight")

    # 获取窗口高度
    window_height = driver.execute_script("return window.innerHeight")
    zoom_level = 1.0
    # 如果页面高度大于窗口高度，缩小页面比例
    while total_height > window_height / zoom_level:
        zoom_level = driver.execute_script("return document.body.style.zoom")
        zoom_level = float(zoom_level) if zoom_level else 1.0
        zoom_level -= 0.02
        driver.execute_script(f"document.body.style.zoom = '{zoom_level}'")
        total_height = driver.execute_script("return document.body.scrollHeight")

    driver.save_screenshot(file_path)
    # 还原页面比例
    driver.execute_script("document.body.style.zoom = '1.0'")


def get_file_name(Type, title):
    """
    获取文件名
    :param platform: 平台
    :param user: 用户
    :param Type: 类型
    :param title: 标题
    :return:文件名
    时间_平台_用户信息_类型_标题
    """
    current_time = datetime.now().strftime("%H：%M：%S")
    return f"{current_time}_{Type}_{title}.png"


class LogUtil:
    _instance = None

    # 单例模式
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(LogUtil, cls).__new__(cls)
        return cls._instance

    def __init__(self, log_dir=log_path, max_bytes=300 * 1024 * 1024, backup_count=10):
        if not hasattr(self, 'logger'):  # 确保只初始化一次
            if not os.path.exists(log_dir):
                os.makedirs(log_dir)

            date_str = datetime.now().strftime("%Y-%m-%d")
            formatted_log_filename = f"{date_str}.log"
            full_log_path = os.path.join(log_dir, formatted_log_filename)

            self.logger = logging.getLogger(full_log_path)
            self.logger.setLevel(logging.DEBUG)

            handler = SizedTimedRotatingFileHandler(full_log_path, maxBytes=max_bytes, backupCount=backup_count,
                                                    when="midnight", interval=1, encoding='utf-8')
            formatter = logging.Formatter('[%(asctime)s]【%(levelname)s】%(message)s')
            handler.setFormatter(formatter)
            self.logger.addHandler(handler)
            self.logger.propagate = False  # 防止日志事件传播到更高级别的日志记录器

            self.log_callback = None  # Tkinter的日志显示回调

    def log(self, message, level=logging.INFO):
        import traceback
        try:
            tb_str = traceback.format_exception(etype=type(message), value=message, tb=message.__traceback__)
            message = f"{''.join(tb_str)}"
        except:
            pass

        if level == logging.DEBUG:
            self.logger.debug(message)
        elif level == logging.INFO:
            self.logger.info(message)
        elif level == logging.WARNING:
            self.logger.warning(message)
        elif level == logging.ERROR:
            self.logger.error(message)
        elif level == logging.CRITICAL:
            self.logger.critical(message)

    def tk_log(self, message):
        if not self.log_callback: raise Exception("未设置Tkinter的日志显示回调")
        # 加入时间
        message = f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {message}"
        self.log_callback(message)  # 调用Tkinter回调来显示日志

    def set_tk_log_callback(self, callback):
        # 设置Tkinter的日志显示回调
        self.log_callback = callback


class SizedTimedRotatingFileHandler(TimedRotatingFileHandler):
    """
    A handler that rotates log files at certain timed intervals, but also considers the size of the file.
    """

    def __init__(self, filename, maxBytes, backupCount, when, interval, encoding=None, delay=False, utc=False):
        TimedRotatingFileHandler.__init__(self, filename, when, interval, backupCount, encoding, delay, utc)
        self.maxBytes = maxBytes

    def shouldRollover(self, record):
        """
        Determine if rollover should occur.

        Basically, see if the supplied record would cause the file to exceed the size limit we have.
        """
        if self.stream is None:  # delay was set...
            self.stream = self._open()
        if self.maxBytes > 0:  # are we rolling over based on size?
            msg = f"{self.format(record)}\n"
            self.stream.seek(0, 2)  # go to the end of the file
            if self.stream.tell() + len(msg) >= self.maxBytes:
                return 1
        return TimedRotatingFileHandler.shouldRollover(self, record)


log_util = LogUtil()
